using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace RandomRat {

	/// <summary>
	/// Summary description for GenerateSets.
	/// </summary>
	public class GenerateSets : System.Windows.Forms.Form {

		Thread workerThread;
		RandomSetGenerator rndSetGen;
		ArrayList rndSets;
		SetArguments setArgs;
		CriteriaFormState formState;
		bool _generatedSets;

		Form1 form1;
		
		#region WINVARS

		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.TabControl tabControl1;
		private System.Windows.Forms.TabPage tabPage1;
		private System.Windows.Forms.TabPage tabPage2;
		private System.Windows.Forms.Button butNext;
		private System.Windows.Forms.Button butAbort;
		private System.Windows.Forms.ProgressBar progressBar1;
		private System.Windows.Forms.GroupBox groupBox3;
		private System.Windows.Forms.Button butCopyToClipboard;
		private System.Windows.Forms.Button butSaveAs;
		private System.Windows.Forms.Button butPrintPreview;
		private System.Windows.Forms.Button butPrint;
		private System.Windows.Forms.Button butExport;
		private NumberBox txtSets;
		private System.Windows.Forms.Button butBack;
		private System.Windows.Forms.Button butCancel;
		private System.Windows.Forms.Label label1;
		private System.ComponentModel.Container components = null;

		#endregion

		public GenerateSets(CriteriaFormState formState, Form1 form1) {
			InitializeComponent();
			
			this.formState = formState;
			this.setArgs = formState.ToSetArguments();
			this.form1 = form1;
			rndSetGen = new RandomSetGenerator();

			this.txtSets.Text = formState.Sets;
		}

		public bool GeneratedSets {
			get { return _generatedSets; }
		}

		public ArrayList RndSets {
			get { return rndSets; }
		}

		public string Sets {
			get { return txtSets.Text; }
		}

		private void generateSets() {			
			progressBar1.Value = progressBar1.Minimum;
			
			if (txtSets.Text.Trim() == "") {
				MessageBox.Show(this, "Please provide a value for 'Generate sets.'");
				txtSets.Focus();
				txtSets.SelectAll();
				return;
			}
			int setsToGen = int.Parse(txtSets.Text);

			if (setsToGen < 1) {
				MessageBox.Show(this, "'Generate sets' must be greater than 0.");
				txtSets.Focus();
				txtSets.SelectAll();
				return;
			}

			// Nav to next page
			//label2.Text = "Generating sets...";
			tabControl1.SelectedIndex++;
			
			workerThread = new Thread(new ThreadStart(this.DoWork));
			workerThread.Start();
		}

        int lastSetsToGen = -1;

        void preDoWork_UI()
        {
            butPrint.Enabled = false;
            butPrintPreview.Enabled = false;
            butSaveAs.Enabled = false;
            butCopyToClipboard.Enabled = false;
            butBack.Enabled = false;

            butAbort.Text = "Abort";
            butAbort.Enabled = true;

            // Get sets to gen
            lastSetsToGen = int.Parse(txtSets.Text);
        }

        void postDoWork_UI()
        {
            //butAbort.Enabled = false;
            butAbort.Text = "Close";
            _generatedSets = true;

            this.Text = "Select an action";
            butPrint.Enabled = true;
            butPrintPreview.Enabled = true;
            butSaveAs.Enabled = true;
            butCopyToClipboard.Enabled = true;
            butBack.Enabled = true;
        }
       
		private void DoWork() {

            this.Invoke(new UIWork(preDoWork_UI));
			// Do generating
            rndSets = genRndSets(lastSetsToGen);

            this.Invoke(new UIWork(postDoWork_UI));
			
		}

        private void preGenRndSets_progUI()
        {
            progressBar1.Minimum = 1;
            progressBar1.Maximum = lastSetsToGen + 1;
            progressBar1.Value = 1;
        }

        private void incGenRndSets_progUI()
        {
            progressBar1.Value += 1;
        }


		// Called from doWork (via the WorkingThread)
		// Generates n rndSets while updating the progress bar
		private ArrayList genRndSets(int setsToGen) {

            Invoke(new UIWork(preGenRndSets_progUI));
            
            rndSets = new ArrayList();

			int i;
			for (i = 0; i < setsToGen; i++) {
				rndSets.Add(rndSetGen.GetValidList(setArgs));
                Invoke(new UIWork(incGenRndSets_progUI));
			}

			return rndSets;
		}



		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.txtSets = new NumberBox();
			this.tabControl1 = new System.Windows.Forms.TabControl();
			this.tabPage1 = new System.Windows.Forms.TabPage();
			this.butCancel = new System.Windows.Forms.Button();
			this.butNext = new System.Windows.Forms.Button();
			this.tabPage2 = new System.Windows.Forms.TabPage();
			this.groupBox3 = new System.Windows.Forms.GroupBox();
			this.butExport = new System.Windows.Forms.Button();
			this.butCopyToClipboard = new System.Windows.Forms.Button();
			this.butSaveAs = new System.Windows.Forms.Button();
			this.butPrintPreview = new System.Windows.Forms.Button();
			this.butPrint = new System.Windows.Forms.Button();
			this.progressBar1 = new System.Windows.Forms.ProgressBar();
			this.butAbort = new System.Windows.Forms.Button();
			this.butBack = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.groupBox1.SuspendLayout();
			this.tabControl1.SuspendLayout();
			this.tabPage1.SuspendLayout();
			this.tabPage2.SuspendLayout();
			this.groupBox3.SuspendLayout();
			this.SuspendLayout();
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] {
																					this.label1,
																					this.txtSets});
			this.groupBox1.Location = new System.Drawing.Point(14, 24);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(296, 108);
			this.groupBox1.TabIndex = 22;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Options:";
			// 
			// txtSets
			// 
			this.txtSets.Location = new System.Drawing.Point(96, 40);
			this.txtSets.Name = "txtSets";
			this.txtSets.Size = new System.Drawing.Size(44, 20);
			this.txtSets.TabIndex = 2;
			this.txtSets.Text = "";
			// 
			// tabControl1
			// 
			this.tabControl1.Controls.AddRange(new System.Windows.Forms.Control[] {
																					  this.tabPage1,
																					  this.tabPage2});
			this.tabControl1.Location = new System.Drawing.Point(-12, -28);
			this.tabControl1.Name = "tabControl1";
			this.tabControl1.SelectedIndex = 0;
			this.tabControl1.Size = new System.Drawing.Size(332, 212);
			this.tabControl1.TabIndex = 24;
			this.tabControl1.TabStop = false;
			this.tabControl1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tabControl1_KeyDown);
			// 
			// tabPage1
			// 
			this.tabPage1.Controls.AddRange(new System.Windows.Forms.Control[] {
																				   this.butCancel,
																				   this.butNext,
																				   this.groupBox1});
			this.tabPage1.Location = new System.Drawing.Point(4, 22);
			this.tabPage1.Name = "tabPage1";
			this.tabPage1.Size = new System.Drawing.Size(324, 186);
			this.tabPage1.TabIndex = 0;
			this.tabPage1.Text = "tabPage1";
			// 
			// butCancel
			// 
			this.butCancel.Location = new System.Drawing.Point(12, 156);
			this.butCancel.Name = "butCancel";
			this.butCancel.TabIndex = 29;
			this.butCancel.Text = "Cancel";
			this.butCancel.Click += new System.EventHandler(this.butCancel_Click);
			// 
			// butNext
			// 
			this.butNext.Location = new System.Drawing.Point(236, 156);
			this.butNext.Name = "butNext";
			this.butNext.TabIndex = 28;
			this.butNext.Text = "Next >";
			this.butNext.Click += new System.EventHandler(this.butNext_Click);
			// 
			// tabPage2
			// 
			this.tabPage2.Controls.AddRange(new System.Windows.Forms.Control[] {
																				   this.groupBox3,
																				   this.progressBar1,
																				   this.butAbort,
																				   this.butBack});
			this.tabPage2.Location = new System.Drawing.Point(4, 22);
			this.tabPage2.Name = "tabPage2";
			this.tabPage2.Size = new System.Drawing.Size(324, 186);
			this.tabPage2.TabIndex = 1;
			this.tabPage2.Text = "tabPage2";
			// 
			// groupBox3
			// 
			this.groupBox3.Controls.AddRange(new System.Windows.Forms.Control[] {
																					this.butExport,
																					this.butCopyToClipboard,
																					this.butSaveAs,
																					this.butPrintPreview,
																					this.butPrint});
			this.groupBox3.Location = new System.Drawing.Point(72, 14);
			this.groupBox3.Name = "groupBox3";
			this.groupBox3.Size = new System.Drawing.Size(180, 132);
			this.groupBox3.TabIndex = 25;
			this.groupBox3.TabStop = false;
			this.groupBox3.Text = "Action:";
			// 
			// butExport
			// 
			this.butExport.Enabled = false;
			this.butExport.Location = new System.Drawing.Point(7, 100);
			this.butExport.Name = "butExport";
			this.butExport.Size = new System.Drawing.Size(164, 23);
			this.butExport.TabIndex = 5;
			this.butExport.Text = "Export";
			// 
			// butCopyToClipboard
			// 
			this.butCopyToClipboard.Location = new System.Drawing.Point(7, 73);
			this.butCopyToClipboard.Name = "butCopyToClipboard";
			this.butCopyToClipboard.Size = new System.Drawing.Size(164, 23);
			this.butCopyToClipboard.TabIndex = 3;
			this.butCopyToClipboard.Text = "Copy to Clipboard";
			this.butCopyToClipboard.Click += new System.EventHandler(this.butCopyToClipboard_Click);
			// 
			// butSaveAs
			// 
			this.butSaveAs.Location = new System.Drawing.Point(7, 46);
			this.butSaveAs.Name = "butSaveAs";
			this.butSaveAs.Size = new System.Drawing.Size(164, 23);
			this.butSaveAs.TabIndex = 2;
			this.butSaveAs.Text = "Save As";
			this.butSaveAs.Click += new System.EventHandler(this.butSaveAs_Click);
			// 
			// butPrintPreview
			// 
			this.butPrintPreview.Location = new System.Drawing.Point(91, 19);
			this.butPrintPreview.Name = "butPrintPreview";
			this.butPrintPreview.Size = new System.Drawing.Size(80, 23);
			this.butPrintPreview.TabIndex = 1;
			this.butPrintPreview.Text = "Print Preview";
			this.butPrintPreview.Click += new System.EventHandler(this.butPrintPreview_Click);
			// 
			// butPrint
			// 
			this.butPrint.Location = new System.Drawing.Point(8, 19);
			this.butPrint.Name = "butPrint";
			this.butPrint.Size = new System.Drawing.Size(80, 23);
			this.butPrint.TabIndex = 0;
			this.butPrint.Text = "Print";
			this.butPrint.Click += new System.EventHandler(this.butPrint_Click);
			// 
			// progressBar1
			// 
			this.progressBar1.Location = new System.Drawing.Point(92, 156);
			this.progressBar1.Name = "progressBar1";
			this.progressBar1.Size = new System.Drawing.Size(140, 23);
			this.progressBar1.TabIndex = 9;
			// 
			// butAbort
			// 
			this.butAbort.Location = new System.Drawing.Point(236, 156);
			this.butAbort.Name = "butAbort";
			this.butAbort.TabIndex = 8;
			this.butAbort.Text = "Abort";
			this.butAbort.Click += new System.EventHandler(this.butAbort_Click);
			// 
			// butBack
			// 
			this.butBack.Location = new System.Drawing.Point(12, 156);
			this.butBack.Name = "butBack";
			this.butBack.TabIndex = 7;
			this.butBack.Text = "< Back";
			this.butBack.Click += new System.EventHandler(this.butBack_Click);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(12, 44);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(80, 16);
			this.label1.TabIndex = 3;
			this.label1.Text = "Generate sets:";
			// 
			// GenerateSets
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(308, 178);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.tabControl1});
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "GenerateSets";
			this.ShowInTaskbar = false;
			this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "Generate";
			this.Closing += new System.ComponentModel.CancelEventHandler(this.GenerateSets_Closing);
			this.groupBox1.ResumeLayout(false);
			this.tabControl1.ResumeLayout(false);
			this.tabPage1.ResumeLayout(false);
			this.tabPage2.ResumeLayout(false);
			this.groupBox3.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		private void tabControl1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
			if (e.KeyCode == Keys.Left) {
				//chkShowOnStartUp.Focus();
				//e.Handled = true;
			} else if (e.KeyCode == Keys.Right) {
				//butCloseQuickStart.Focus();
				//e.Handled = true;
			}
		}

		private void butNext_Click(object sender, System.EventArgs e) {
			generateSets();
		}

		private void butAbort_Click(object sender, System.EventArgs e) {
			if (butAbort.Text.CompareTo("Abort") == 0 && 
				workerThread != null && workerThread.IsAlive) {
				
				workerThread.Abort();
				_generatedSets = false;
				//label2.Text = "Set generation aborted";
			} else if (butAbort.Text.CompareTo("Close") == 0) {
				this.Close();
			}
			butAbort.Enabled = false;
			butBack.Enabled = true;
		}

		private void butPrint_Click(object sender, System.EventArgs e) {
			printSets();
		}

		private void butPrintPreview_Click(object sender, System.EventArgs e) {
			printPreviewSets();
		}

		private void butSaveAs_Click(object sender, System.EventArgs e) {
			saveSetsAs();
		}

		private void butCopyToClipboard_Click(object sender, System.EventArgs e) {
			copyToClip();
		}

		private void printSets() {
			RandomSetPrinter setPrinter = new RandomSetPrinter(rndSets, setArgs, this);
            setPrinter.Print(RandomSetPrintMode.PrintWithDiolog, this);
		}

		private void printPreviewSets() {
			RandomSetPrinter setPrinter = new RandomSetPrinter(rndSets, setArgs, this);
            setPrinter.Print(RandomSetPrintMode.PrintPreview, this);
		}

		private void saveSetsAs() {
			DataManager.SaveSetsToFile(rndSets, formState, SetsFileType.Multiple);
		}

		private void copyToClip() {
			DataManager.CopySetsToClipboard(rndSets, setArgs);
			MessageBox.Show(this, "The sets have been copied to the clipboard.");
		}

		private void butBack_Click(object sender, System.EventArgs e) {
			tabControl1.SelectedIndex--;
		}

		private void butCancel_Click(object sender, System.EventArgs e) {
			this.Close();
		}

		private void GenerateSets_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
			if (workerThread != null && workerThread.IsAlive) {
				workerThread.Abort();
			}
		}

	}
}
